package com.javabank.ws.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import com.javabank.ws.dao.BaseDAO;

public class BaseDAOImpl<T> extends BasePersistence implements BaseDAO<T> {

    /**
     *
     * @param t
     */
    @Override
    public void add(T t) {
        open();
        em.getTransaction().begin();
        em.merge(t);
        em.getTransaction().commit();
        close();
    }

    /**
     *
     * @param t
     */
    @Override
    public void delete(T t) {
        open();
        em.getTransaction().begin();
        em.remove(em.merge(t));
        em.getTransaction().commit();
        close();
    }

    /**
     *
     * @param id
     * @return
     */
    @Override
    public T getById(int id) {
        Class clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        open();
        T t = (T) em.find(clazz, id);
        close();
        return t;
    }

    /**
     *
     * @param c
     * @param id
     * @return
     */
    @Override
    public T getById(Class<T> c, int id) {
        open();
        T t = em.find(c, id);
        close();
        return t;
    }
    
    /**
     * 
     * @param t 
     */
    @Override
    public void update(T t) {
        open();
        em.getTransaction().begin();
        em.merge(t);
        em.getTransaction().commit();
        close();
    }

    /**
     * 
     * @return 
     */
    @Override
    public List<T> getAll() {
        Class clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

        open();
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<T> criteriaQuery = (CriteriaQuery<T>) cb.createQuery();
        Root<T> from = criteriaQuery.from(clazz);
        CriteriaQuery<T> select = criteriaQuery.select(from);
        TypedQuery<T> typedQuery = em.createQuery(select);
       
        return typedQuery.getResultList();
    }
}